package com.sunwayworld.basemodule.common.utils;

import com.aspose.words.*;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import com.sunwayworld.framework.utils.ObjectUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FilenameUtils;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.*;

public class AsposeWordUtils {
    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = AsposeWordUtils.class.getClassLoader().getResourceAsStream("license.xml"); // license.xml应放在..\WebRoot\WEB-INF\classes路径下
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static void doc2pdf(String inPath, String outPath) {
        if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
            return;
        }
        try {
            long old = System.currentTimeMillis();
            File file = new File(outPath); // 新建一个空白pdf文档
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            FileOutputStream os = new FileOutputStream(file);
            Document doc = new Document(inPath); // Address是将要被转化的word文档
            doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
            os.close(); // EPUB, XPS, SWF 相互转换
            long now = System.currentTimeMillis();
            //log.info("共耗时：" + ((now - old) / 1000.0) + "秒"); // 转化用时
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void doc2docx(String inPath, String outPath) {
        if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
            return;
        }
        try {
            long old = System.currentTimeMillis();
            File file = new File(outPath); // 新建一个空白pdf文档
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            FileOutputStream os = new FileOutputStream(file);
            Document doc = new Document(inPath); // Address是将要被转化的word文档
            doc.save(os, SaveFormat.DOCX);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
            os.close(); // EPUB, XPS, SWF 相互转换
            long now = System.currentTimeMillis();
            //log.info("共耗时：" + ((now - old) / 1000.0) + "秒"); // 转化用时
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void insertPdfdocument(String docxPath, String pdfPath) {
        doc2pdf(docxPath, pdfPath);
    }

    public static void waterMark(String inputFile, String outputFile, String waterMarkName) {
        PdfReader reader = null;
        PdfStamper stamper = null;
        try {
            reader = new PdfReader(inputFile);
            stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            Rectangle pageRect = null;
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.3f);
            gs.setStrokeOpacity(0.4f);
            int total = reader.getNumberOfPages() + 1;

            JLabel label = new JLabel();
            FontMetrics metrics;
            int textH = 0;
            int textW = 0;
            label.setText(waterMarkName);
            metrics = label.getFontMetrics(label.getFont());
            textH = metrics.getHeight();
            textW = metrics.stringWidth(label.getText());

            PdfContentByte under;
            for (int i = 1; i < total; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                under = stamper.getOverContent(i);
                under.saveState();
                under.setGState(gs);
                under.beginText();
                under.setFontAndSize(base, 100);

                // 水印文字成30度角倾斜
                // 你可以随心所欲的改你自己想要的角度
                under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, textW + pageRect.getWidth() / 2,
                        textH + pageRect.getHeight() / 2, 30);
                // 添加水印文字
                under.endText();
            }
            // 一定不要忘记关闭流
            stamper.close();
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                stamper.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            reader.close();
        }
    }

    /**
     * 给pdf加图片水印、文字水印；
     * 可以选择图片水印或者文字水印，或者2者都有。
     *
     * @param inputPdfFile
     * @param outputPdfFile
     * @param imgFile
     * @param usercode
     * @param userdesc
     * @throws Exception
     */
    public static void imageWaterAndTextMark(String inputPdfFile, String outputPdfFile, String imgFile, String usercode, String userdesc) throws Exception {
        PdfReader reader = null;
        PdfStamper stamp = null;
        try {
            reader = new PdfReader(inputPdfFile);
            stamp = new PdfStamper(reader, new FileOutputStream(outputPdfFile));
            Rectangle pageRect = null;
            PdfGState gs1 = new PdfGState();
            gs1.setFillOpacity(0.3f);
            gs1.setStrokeOpacity(0.4f);

            Image image = null;
            if (!ObjectUtils.isEmpty(imgFile)) {
//                String scaleImgFile = new File(imgFile).getParent()+File.separator+"scaleWaterImg.png";
//                ImageUtils.scale(imgFile,scaleImgFile,60,60,true);
                image = Image.getInstance(imgFile);
                image.setRotationDegrees(30);
            }

            int n = reader.getNumberOfPages();
            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            for (int i = 1; i <= n; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                PdfContentByte pdfContentByte = stamp.getOverContent(i);
                pdfContentByte.saveState();
                pdfContentByte.setGState(gs1);
                //每页铺设3个
                for (int j = 0; j <= 3; j++) {
                    //图片水印
                    float x = pageRect.getWidth() / 2 - image.getWidth() / 2;
                    float y = pageRect.getHeight() / 2 - image.getHeight() / 2;
                    if (image != null) {
                        image.setAbsolutePosition(x, j * pageRect.getHeight() / 4);
                        pdfContentByte.addImage(image);
                    }

                    //文字水印
                    if (!ObjectUtils.isEmpty(usercode) && !ObjectUtils.isEmpty(userdesc)) {
                        pdfContentByte.beginText();
                        pdfContentByte.setFontAndSize(baseFont, 20);
                        String textWater = userdesc + usercode;
                        String dateWater = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                        pdfContentByte.showTextAligned(Element.ALIGN_CENTER, textWater, x,
                                j * pageRect.getHeight() / 4 + 80, 30);
                        pdfContentByte.showTextAligned(Element.ALIGN_CENTER, dateWater, x,
                                j * pageRect.getHeight() / 4 + 60, 30);
                        pdfContentByte.endText();
                    }
                }
            }
        } finally {
            if (stamp != null) {
                stamp.close();
            }
            if (reader != null) {
                reader.close();
            }
        }
    }

    /**
     * 通过书签来插入html内容，因为可以插入html
     *
     * @param mainPath  输入文件
     * @param outPath   输出文件
     * @param bookMarks map,key=书签，value=html内容
     * @throws Exception
     */
    public static void insertHtmlToWord(String mainPath, String outPath, Map<String, String> bookMarks) throws Exception {
        Document temdoc = new Document(mainPath);
        DocumentBuilder docBuilder = new DocumentBuilder(temdoc);
        for (Map.Entry<String, String> entry : bookMarks.entrySet()) {
            String key = entry.getKey();
            String html = entry.getValue();
            boolean b = docBuilder.moveToBookmark(key);
            if (b) {
                Paragraph currentParagraph = docBuilder.getCurrentParagraph();
                NodeCollection childNodes = currentParagraph.getChildNodes();
                Iterator iterator = childNodes.iterator();
                while (iterator.hasNext()) {
                    Node child = (Node) iterator.next();
                    //保留书签，清空内容
                    if (!(child instanceof BookmarkStart || child instanceof BookmarkEnd)) {
                        currentParagraph.removeChild(child);
                    }
                }
                docBuilder.insertHtml(html, true);
            }
        }
        temdoc.save(outPath);
    }

    public static void insertImageToWord(String mainPath, String outPath, List<Map<String, String>> bookMarks) throws Exception {
        Document temdoc = new Document(mainPath);
        DocumentBuilder docBuilder = new DocumentBuilder(temdoc);
        for (Map<String, String> map : bookMarks) {
            String bookMark = map.get("bookMark");
            String imgPath = map.get("imgPath");
            double width = Double.parseDouble(map.get("width"));
            double height = Double.parseDouble(map.get("height"));
            boolean b = docBuilder.moveToBookmark(bookMark);
            if (b) {
                Paragraph currentParagraph = docBuilder.getCurrentParagraph();
                NodeCollection childNodes = currentParagraph.getChildNodes();
                Iterator iterator = childNodes.iterator();
                while (iterator.hasNext()) {
                    Node child = (Node) iterator.next();
                    //保留书签，清空内容
                    if (!(child instanceof BookmarkStart || child instanceof BookmarkEnd)) {
                        currentParagraph.removeChild(child);
                    }
                }
                docBuilder.insertImage(new FileInputStream(imgPath), width, height);
            }
        }
        temdoc.save(outPath);
    }

    /**
     * 更新域代码，比如word中的交叉引用的页码
     *
     * @throws Exception
     */
    public static void updateFields(String mainPath, String outPath) throws Exception {
        Document temdoc = new Document(mainPath);
        temdoc.updateFields();
        temdoc.save(outPath);
    }

    /**
     * 判定文件是否能够参与插入到word中
     *
     * @param path
     * @return
     */
    public static boolean canMergeWordImgPdfToWord(String path) {
        boolean can = false;
        String suffix = path.substring(path.lastIndexOf(".") + 1);
        if (suffix.equalsIgnoreCase("pdf")) {
            can = true;
        } else if (suffix.equalsIgnoreCase("doc") || suffix.equalsIgnoreCase("docx")) {
            can = true;
        } else if (suffix.equalsIgnoreCase("bmp") || suffix.equalsIgnoreCase("dib") || suffix.equalsIgnoreCase("gif")
                || suffix.equalsIgnoreCase("jfif") || suffix.equalsIgnoreCase("jpe") || suffix.equalsIgnoreCase("jpeg")
                || suffix.equalsIgnoreCase("jpg") || suffix.equalsIgnoreCase("png") || suffix.equalsIgnoreCase("tif")
                || suffix.equalsIgnoreCase("tiff") || suffix.equalsIgnoreCase("ico")) {
            can = true;
        }
        return can;
    }

    /**
     * @param baseWordPath   基准word
     * @param sourcePathList 要合并到基准word中的文件，文件类型是图片，word,pdf
     * @throws Exception
     */
    public static void mergeWordImgPdfToWord(String baseWordPath, String outWordPath, List<String> sourcePathList, String endParaText) throws Exception {
        Document temdoc = new Document(baseWordPath);
        DocumentBuilder docBuilder = new DocumentBuilder(temdoc);
        docBuilder.moveToDocumentEnd();
        docBuilder.insertBreak(BreakType.PARAGRAPH_BREAK);

        for (String path : sourcePathList) {
            String suffix = path.substring(path.lastIndexOf(".") + 1);
            if (suffix.equalsIgnoreCase("pdf")) {
                String imgDirPath = new File(path).getParent(); //于pdf同一目录
                List<String> imagePaths = FileUtils.pdfToImagePath(path, imgDirPath);  //pdf每页转成一张图片
                if (CollectionUtils.isNotEmpty(imagePaths)) {
                    for (String imgPath : imagePaths) {
                        docBuilder.insertImage(imgPath);
                        docBuilder.insertBreak(BreakType.PARAGRAPH_BREAK);
                    }
                }
            } else if (suffix.equalsIgnoreCase("doc") || suffix.equalsIgnoreCase("docx")) {
                docBuilder.insertDocument(new Document(path), ImportFormatMode.KEEP_DIFFERENT_STYLES);
                docBuilder.insertBreak(BreakType.PARAGRAPH_BREAK);
            } else if (suffix.equalsIgnoreCase("bmp") || suffix.equalsIgnoreCase("dib") || suffix.equalsIgnoreCase("gif")
                    || suffix.equalsIgnoreCase("jfif") || suffix.equalsIgnoreCase("jpe") || suffix.equalsIgnoreCase("jpeg")
                    || suffix.equalsIgnoreCase("jpg") || suffix.equalsIgnoreCase("png") || suffix.equalsIgnoreCase("tif")
                    || suffix.equalsIgnoreCase("tiff") || suffix.equalsIgnoreCase("ico")) {
                docBuilder.insertImage(path);
                docBuilder.insertBreak(BreakType.PARAGRAPH_BREAK);
            }
        }
        if (!ObjectUtils.isEmpty(endParaText)) {
            docBuilder.insertHtml(endParaText, true);
        }
        temdoc.save(outWordPath);
    }

    /**
     * 图片转pdf
     *
     * @param os
     * @throws Exception
     */
    public static void imgToPdf(String imgPath, OutputStream os) throws Exception {
        com.itextpdf.text.Document document = new com.itextpdf.text.Document();
        PdfWriter.getInstance(document, os);
        document.open();
        Image image = Image.getInstance(imgPath);
        document.add(image);
        document.close();
    }

    public static void imgToPdf(String imgPath, String outpdfPath) throws Exception {
        com.itextpdf.text.Document document = new com.itextpdf.text.Document();
        OutputStream os = new FileOutputStream(outpdfPath);
        PdfWriter.getInstance(document, os);
        document.open();
        Image image = Image.getInstance(imgPath);
        document.add(image);
        document.close();
        os.close();
    }

    /**
     * 取交集
     *
     * @param lists
     * @return
     */
    public static <E> List<E> findSameElem(List<List<E>> lists) {
        if (lists.size() == 0) return Collections.emptyList();
        List<E> firstList = lists.get(0);
        List<E> tmpList = new ArrayList<>(lists.get(0));
        for (int i = 1; i < lists.size(); i++) {
            List<E> aList = lists.get(i);
            tmpList.retainAll(aList);
        }
        return tmpList;
    }

    /**
     * 通过书签来插入文件到word中
     */
    public static void mergeFileToWordByBookMark(String wordFilePath, String outWordPath, List<Map<String, Object>> bookMarks) throws Exception {
        Document temdoc = new Document(wordFilePath);
        DocumentBuilder docBuilder = new DocumentBuilder(temdoc);
        for (Map<String, Object> b : bookMarks) {
            String mark = ObjectUtils.toString(b.get("mark"));
            String filePath = ObjectUtils.toString(b.get("filePath")); //书签插入文件
            List<String> richTexts = (List<String>) b.get("richTexts");  //书签插入富文本
            String replaceText = ObjectUtils.toString(b.get("replaceText")); //替换文本
            String replaceImg = ObjectUtils.toString(b.get("replaceImg")); //替换签名图片
            if (!ObjectUtils.isEmpty(mark) && !ObjectUtils.isEmpty(filePath) && docBuilder.moveToBookmark(mark)) {
                String suffix = FilenameUtils.getExtension(filePath);
                if (suffix.equalsIgnoreCase("pdf")) {
                    String imgDirPath = new File(filePath).getParent(); //于pdf同一目录
                    List<String> imagePaths = FileUtils.pdfToImagePath(filePath, imgDirPath);  //pdf每页转成一张图片
                    if (!ObjectUtils.isEmpty(imagePaths)) {
                        for (String imgPath : imagePaths) {
                            docBuilder.insertImage(imgPath);
//                            docBuilder.insertBreak(BreakType.PAGE_BREAK);
                        }
                    }
                } else if (suffix.equalsIgnoreCase("doc") || suffix.equalsIgnoreCase("docx") || suffix.equalsIgnoreCase("rtf")) {
                    docBuilder.insertDocument(new Document(filePath), ImportFormatMode.KEEP_DIFFERENT_STYLES);
//                    docBuilder.insertBreak(BreakType.PAGE_BREAK);
                } else if (suffix.equalsIgnoreCase("bmp") || suffix.equalsIgnoreCase("dib") || suffix.equalsIgnoreCase("gif")
                        || suffix.equalsIgnoreCase("jfif") || suffix.equalsIgnoreCase("jpe") || suffix.equalsIgnoreCase("jpeg")
                        || suffix.equalsIgnoreCase("jpg") || suffix.equalsIgnoreCase("png") || suffix.equalsIgnoreCase("tif")
                        || suffix.equalsIgnoreCase("tiff") || suffix.equalsIgnoreCase("ico")) {
                    docBuilder.insertImage(filePath);
//                    docBuilder.insertBreak(BreakType.PAGE_BREAK);
                }/* else if (suffix.equalsIgnoreCase("xlsx") || suffix.equalsIgnoreCase("xls")) {
                    String dir = new File(filePath).getParent();
                    String pdfName = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase() + ".pdf";
                    String pdfPath = dir + File.separator + pdfName;
                    AsposeExcelUtils.convertExcelToPdf(filePath, pdfPath);
                    String imgDirPath = new File(pdfPath).getParent(); //于pdf同一目录
                    List<String> imagePaths = FileUtils.pdfToImagePath(pdfPath, imgDirPath);  //pdf每页转成一张图片
                    if (!ObjectUtils.isEmpty(imagePaths)) {
                        for (String imgPath : imagePaths) {
                            docBuilder.insertImage(imgPath);
//                            docBuilder.insertBreak(BreakType.PAGE_BREAK);
                        }
                    }
                }*/
            }

            if (!ObjectUtils.isEmpty(mark) && !ObjectUtils.isEmpty(richTexts) && docBuilder.moveToBookmark(mark)) {
                for (String rich : richTexts) {
                    docBuilder.insertHtml(rich);
                    docBuilder.insertBreak(BreakType.PARAGRAPH_BREAK);
                }
            }

            if (!ObjectUtils.isEmpty(replaceText) && docBuilder.moveToBookmark(mark)) {
                Paragraph currentParagraph = docBuilder.getCurrentParagraph();
                NodeCollection childNodes = currentParagraph.getChildNodes();
                Iterator iterator = childNodes.iterator();
                while (iterator.hasNext()) {
                    Node child = (Node) iterator.next();
                    //保留书签，清空内容
                    if (!(child instanceof BookmarkStart || child instanceof BookmarkEnd)) {
                        currentParagraph.removeChild(child);
                    }
                }

                docBuilder.insertHtml(replaceText, false);
            }

            if (!ObjectUtils.isEmpty(replaceImg) && docBuilder.moveToBookmark(mark)) {
                Paragraph currentParagraph = docBuilder.getCurrentParagraph();
                NodeCollection childNodes = currentParagraph.getChildNodes();
                Iterator iterator = childNodes.iterator();
                while (iterator.hasNext()) {
                    Node child = (Node) iterator.next();
                    //保留书签，清空内容
                    if (!(child instanceof BookmarkStart || child instanceof BookmarkEnd)) {
                        currentParagraph.removeChild(child);
                    }
                }
                docBuilder.insertImage(replaceImg, 54, 27);
            }
        }
        temdoc.save(outWordPath);
    }

}
